import React from "react";
import { useRequest } from "ahooks";
import { Button } from "@/components/ui/button";
import { Switch } from "@/components/ui/switch";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";
import { Heading } from "@/components/ui/heading";
import { Input } from "@/components/ui/input";
import { Separator } from "@/components/ui/separator";
import { Checkbox } from "@/components/ui/checkbox";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { zodResolver } from "@hookform/resolvers/zod";
import {
  ColumnDef,
  ColumnFiltersState,
  createColumnHelper,
  flexRender,
  getCoreRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  SortingState,
  useReactTable,
  VisibilityState,
} from "@tanstack/react-table";
import {
  ArrowUpDown,
  ChevronLeftIcon,
  ChevronRightIcon,
  ChevronsLeft,
  ChevronsRight,
  Edit,
  MoreHorizontal,
  Trash,
  Plus,
} from "lucide-react";
import { useForm } from "react-hook-form";
import * as z from "zod";
import { AlertModal } from "@/components/modal/alert-modal";
import { ResourceI, RoleI, TenantI } from "@/types";
import PageContainer from "@/components/layout/page-container";
import CustomTable from "@/components/ui/custom-table";
import CustomDndTable from "@/components/ui/custom-dnd-table";
import { useToast } from "@/hooks/use-toast";
import {
  createRole,
  updateRole,
  searchRoleList,
  deleteRole,
  searchTenantList,
  searchResourceList,
  getRoleDetail,
} from "@/api";
import { useSearchParams } from "react-router-dom";
import { Loading } from "@/components/ui/loading";

const page: React.FC = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const { toast } = useToast();

  const [title, setTitle] = React.useState<string>("");
  const [description, setDescription] = React.useState<string>("");
  const [isSubmitting, setIsSubmitting] = React.useState<boolean>(false);
  const [isAlertOpen, setIsAlertOpen] = React.useState<boolean>(false);
  const [isDialogOpen, setIsDialogOpen] = React.useState<boolean>(false);
  const [totalCount, setTotalCount] = React.useState<number>(0);
  const [roleList, setRoleList] = React.useState<RoleI[]>([]);
  const [tenantList, setTenantList] = React.useState<TenantI[]>([]);
  const [resourceCount, setResourceCount] = React.useState<number>(0);
  const [resourceList, setResourceList] = React.useState<ResourceI[]>([]);
  const [formData, setFormData] = React.useState<RoleI>();
  // 权限表相关变量
  const [sorting, setSorting] = React.useState<SortingState>([]);
  const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
    []
  );
  const [columnVisibility, setColumnVisibility] =
    React.useState<VisibilityState>({});

  const { loading: loadingTenants, run: searchTenants } = useRequest(
    (paramsString: string) => searchTenantList(paramsString),
    {
      manual: false,
      defaultParams: [location.search.replace(/^\?/, "")],
      onSuccess(resp, params: any) {
        // console.log(params);
        setTenantList(resp.data.data);
        setTotalCount(resp.data.totalCount);
      },
      onError(e: any, params: any) {
        console.error("获取数据失败");
        toast({
          variant: "destructive",
          title: "数据获取失败",
          description: "请检查网络或联系系统管理员",
        });
      },
    }
  );

  const { loading, run } = useRequest(
    (paramsString: string) => searchRoleList(paramsString),
    {
      manual: true,
      defaultParams: [location.search.replace(/^\?/, "")],
      onSuccess(resp, params: any) {
        // console.log(resp.data.data);
        setRoleList(resp.data.data);
        setTotalCount(resp.data.totalCount);
      },
      onError(e: any, params: any) {
        // console.error("获取数据失败");
        toast({
          variant: "destructive",
          title: "数据获取失败",
          description: "请检查网络或联系系统管理员",
        });
      },
    }
  );

  const { loading: loadingResourceList } = useRequest(
    (paramsString: string) => searchResourceList(paramsString),
    {
      manual: false,
      defaultParams: [location.search.replace(/^\?/, "")],
      onSuccess(resp, params) {
        // console.log(resp.data.data);
        setResourceList(resp.data.data);
        setResourceCount(resp.data.totalCount);
      },
      onError(e, params) {
        toast({
          variant: "destructive",
          title: "数据获取失败",
          description: "请检查网络或联系系统管理员",
        });
      },
    }
  );

  const formSchema = z.object({
    id: z.string().optional(),
    name: z.string().trim().min(3, { message: "角色名称至少2个字符" }),
    pinyin: z.string().optional(),
    py: z.string().optional(),
    isActive: z.boolean(),
    tenantId: z
      .string({ required_error: "请选择中心" })
      .trim()
      .min(3, { message: "中心ID长度至少三位" }),
    tenant: z.any().optional(),
    resources: z.any(),
  });

  const defaultValues = {
    id: undefined,
    name: "",
    pinyin: "",
    py: "",
    isActive: true,
    tenantId: "",
    resources: {},
  };

  type FormValuesT = z.infer<typeof formSchema>;

  // 表单部分
  const form = useForm<FormValuesT>({
    resolver: zodResolver(formSchema),
    defaultValues: defaultValues,
  });

  const onUpdateClick = (event: any, data: RoleI) => {
    // console.log(data);
    data &&
      data.id &&
      getRoleDetail(data.id)
        .then(
          (res) => {
            const processedData: any = Object.assign(
              {},
              defaultValues,
              res.data
            );
            // console.log(processedData);
            // 设置权限表状态
            let selection: { [key: string]: boolean } = {};
            processedData.resources
              ? processedData.resources.forEach((item: ResourceI) => {
                  selection[item.name] = true;
                })
              : {};
            console.log(selection);
            processedData.resources = selection;
            console.log(processedData.resources);
            setTitle("修改信息");
            // 避免将受控组件的值设置成null，否则会有警告，影响未知
            form.reset(processedData);
            setFormData(processedData);
            setIsDialogOpen(true);
          },
          (err) => {
            toast({
              variant: "destructive",
              title: "数据提交失败",
              description: `${err.detail}`,
            });
          }
        )
        .catch((err) => {
          toast({
            variant: "destructive",
            title: "打开失败",
            description: "获取条目详情失败",
          });
        });
  };

  const onDeleteConfirm = (event: any, data: RoleI) => {
    try {
      setIsSubmitting(true);
      if (data.id) {
        deleteRole(data.id).then(
          (res: any) => {
            console.log(data);
            console.log(res);
            toast({
              variant: "success",
              title: "删除成功",
              description: "",
            });
            run(searchParams.toString());
          },
          (err) => {
            toast({
              variant: "destructive",
              title: "数据提交失败",
              description: `${err.detail}`,
            });
          }
        );
      }
    } catch (error: any) {
      console.log(error);
      toast({
        variant: "destructive",
        title: "删除失败",
        description: "error",
      });
    } finally {
      setIsSubmitting(false);
      setIsAlertOpen(false);
    }
  };

  const onFormSubmit = async (data: FormValuesT) => {
    let formData: any = JSON.parse(JSON.stringify(data));
    const selectedResources = [];
    for (const key in formData.resources) {
      const result = resourceList.find((item: ResourceI) => {
        return item.name === key;
      });
      if (result) {
        selectedResources.push(result);
      }
    }
    console.log(selectedResources);
    formData.resources = selectedResources;
    try {
      setIsSubmitting(true);
      if (data.id) {
        updateRole(formData)
          .then(
            (res) => {
              console.log(res);
              toast({
                variant: "success",
                title: "提交成功",
                description: "",
              });
              console.log(searchParams);
              run(searchParams.toString());
            },
            (err) => {
              toast({
                variant: "destructive",
                title: "数据提交失败",
                description: `${err.detail}`,
              });
            }
          )
          .catch((err) => {
            console.log(err);
            toast({
              variant: "destructive",
              title: "提交失败",
              description: err.detail,
            });
          });
      } else {
        createRole(formData)
          .then(
            (res) => {
              console.log(res);
              toast({
                variant: "success",
                title: "提交成功",
                description: "",
              });
              run(searchParams.toString());
            },
            (err) => {
              toast({
                variant: "destructive",
                title: "数据提交失败",
                description: `${err.detail}`,
              });
            }
          )
          .catch((err) => {
            console.log(err);
            toast({
              variant: "destructive",
              title: "提交失败",
              description: err.detail,
            });
          });
      }
      setIsSubmitting(false);
      setIsDialogOpen(false);
      form.reset(defaultValues);
      toast({
        variant: "success",
        title: "数据提交成功",
        description: "",
        duration: 1600,
      });
    } catch (error: any) {
      toast({
        variant: "destructive",
        title: "数据提交失败",
        description: "请检查网络或联系系统管理员",
      });
    } finally {
      setIsSubmitting(false);
    }
  };

  const columnHelper = createColumnHelper<RoleI>();

  const columns = [
    columnHelper.display({
      id: "select",
      header: (props) => {
        // console.log(props);
        if (props && props.table) {
          return (
            <Checkbox
              checked={props.table.getIsAllPageRowsSelected()}
              onCheckedChange={(value) =>
                props.table.toggleAllPageRowsSelected(!!value)
              }
              aria-label="Select all"
            />
          );
        } else {
          return <Checkbox aria-label="Select all" />;
        }
      },
      footer: (props) => props.column.id,
      cell: (props) => {
        if (props && props.row) {
          return (
            <Checkbox
              checked={props.row.getIsSelected()}
              onCheckedChange={(value) => props.row.toggleSelected(!!value)}
              aria-label="Select row"
            />
          );
        } else {
          return <Checkbox aria-label="Select row" />;
        }
      },
      enableSorting: false,
    }),
    columnHelper.accessor("id", {
      id: "id",
      header: "ID",
      cell: (props) => {
        if (props && props.row) {
          const { row } = props;
          return <span>{row.getValue("id")}</span>;
        }
      },
      enableSorting: false,
    }),
    columnHelper.accessor("name", {
      id: "name",
      header: "角色名称",
      cell: (props) => {
        if (props && props.row) {
          const { row } = props;
          return <span>{row.getValue("name")}</span>;
        }
      },
      enableSorting: true,
    }),
    columnHelper.accessor("isActive", {
      id: "isActive",
      header: "在用标记",
      cell: (props) => {
        if (props && props.row) {
          const { row } = props;
          return row.getValue("isActive") ? (
            <span>停用</span>
          ) : (
            <span>在用</span>
          );
        }
      },
      enableSorting: false,
    }),
    columnHelper.accessor("tenant.name", {
      id: "tenant.name",
      header: "所属中心",
      enableSorting: true,
    }),
    columnHelper.display({
      header: "操作",
      id: "actions",
      cell: (props) => {
        if (props && props.row) {
          const { row } = props;
          return (
            <>
              <AlertModal
                isOpen={isAlertOpen}
                onClose={() => setIsAlertOpen(false)}
                onConfirm={() => onDeleteConfirm(event, row.original)}
                loading={loading}
              />
              <DropdownMenu modal={false}>
                <DropdownMenuTrigger asChild>
                  <Button variant="ghost" className="h-8 w-8 p-0">
                    <span className="sr-only">选项</span>
                    <MoreHorizontal className="h-4 w-4" />
                  </Button>
                </DropdownMenuTrigger>
                <DropdownMenuContent align="end">
                  <DropdownMenuLabel></DropdownMenuLabel>
                  <DropdownMenuItem
                    onClick={() => onUpdateClick(event, row.original)}
                  >
                    <Edit className="mr-2 h-4 w-4" /> 更新
                  </DropdownMenuItem>
                  {/* <DropdownMenuItem onClick={() => setIsAlertOpen(true)}>
                  <Trash className="mr-2 h-4 w-4" /> 删除
                </DropdownMenuItem> */}
                </DropdownMenuContent>
              </DropdownMenu>
            </>
          );
        }
      },
    }),
  ];

  const resourceColumnHelper = createColumnHelper<ResourceI>();
  const resourceColumns = [
    resourceColumnHelper.display({
      id: "select",
      header: (props) => {
        if (props && props.table) {
          return (
            <Checkbox
              checked={props.table.getIsAllPageRowsSelected()}
              onCheckedChange={(value) =>
                props.table.toggleAllPageRowsSelected(!!value)
              }
              aria-label="Select all"
            />
          );
        } else {
          return <Checkbox aria-label="Select all" />;
        }
      },
      footer: (props) => props.column.id,
      cell: (props) => {
        if (props && props.row) {
          return (
            <Checkbox
              checked={props.row.getIsSelected()}
              onCheckedChange={(value) => props.row.toggleSelected(!!value)}
              aria-label="Select row"
            />
          );
        } else {
          return <Checkbox aria-label="Select row" />;
        }
      },
      enableSorting: false,
      enableHiding: false,
    }),
    resourceColumnHelper.accessor("name", {
      id: "name",
      header: "函数名称",
    }),
    resourceColumnHelper.accessor("methods", {
      id: "methods",
      header: "请求类型",
    }),
    resourceColumnHelper.accessor("summary", {
      id: "summary",
      header: "权限描述",
      cell: (props) => {
        if (props && props.row) {
          const { row } = props;
          return <span>{row.getValue("summary")}</span>;
        }
      },
    }),
    resourceColumnHelper.accessor("description", {
      id: "description",
      header: "详细描述",
    }),
  ];

  React.useEffect(() => {
    // console.log(searchParams.toString());
    run(searchParams.toString());
  }, [searchParams]);

  return (
    <PageContainer>
      <div className="space-y-4">
        {/* <Breadcrumbs items={breadcrumbItems} /> */}

        <div className="flex items-start justify-between">
          <Heading title={`角色列表`} description="每个角色对应不同的权限" />

          <Button
            variant="outline"
            className="p-2 rounded-md"
            onClick={() => {
              // console.log(defaultValues);
              form.reset(defaultValues);
              setTitle("创建角色");
              setIsDialogOpen(!isDialogOpen);
            }}
          >
            <Plus className="mr-2 h-4 w-4" />
            创建
          </Button>
        </div>
        <Separator />
        <CustomDndTable
          defaultFilterColumn="name"
          totalCount={totalCount}
          columns={columns}
          loading={loading}
          data={roleList}
        />

        <Dialog
          open={isDialogOpen}
          onOpenChange={() => setIsDialogOpen(!isDialogOpen)}
        >
          <DialogContent className="max-w-3xl h-[80vh] overflow-y-auto">
            <DialogHeader>
              <DialogTitle></DialogTitle>
              <DialogDescription></DialogDescription>
            </DialogHeader>
            <div className="flex items-center justify-between">
              <Heading title={title} description={description} />
            </div>
            <Separator />
            <div className="">
              <Form {...form}>
                <form
                  onSubmit={form.handleSubmit(onFormSubmit)}
                  className="w-full space-y-8"
                >
                  {/* <div className="gap-8 md:grid md:grid-cols-3"> */}
                  <div className="flex flex-col gap-4">
                    {formData && formData.id ? (
                      <FormField
                        control={form.control}
                        name="id"
                        render={({ field }) => (
                          <FormItem>
                            <FormLabel>ID</FormLabel>
                            <FormControl>
                              <Input
                                placeholder="id"
                                {...field}
                                disabled={
                                  formData && formData.id ? true : false
                                }
                              />
                            </FormControl>
                            <FormMessage />
                          </FormItem>
                        )}
                      />
                    ) : null}
                    <FormField
                      control={form.control}
                      name="name"
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>角色名称</FormLabel>
                          <FormControl>
                            <Input
                              disabled={loading}
                              placeholder="Role name"
                              {...field}
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                    <FormField
                      control={form.control}
                      name="isActive"
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>在用标记</FormLabel>
                          <FormControl>
                            <Switch
                              className="ml-6"
                              checked={field.value}
                              onCheckedChange={field.onChange}
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                    <FormField
                      control={form.control}
                      name="tenantId"
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>中心名称</FormLabel>
                          <FormControl>
                            <Select
                              onValueChange={field.onChange}
                              defaultValue={field.value}
                            >
                              <SelectTrigger className="w-[180px]">
                                <SelectValue placeholder="中心名称" />
                              </SelectTrigger>
                              <SelectContent>
                                {tenantList.map((item: TenantI) => {
                                  return (
                                    <SelectItem value={item.id!} key={item.id}>
                                      {item.name}
                                    </SelectItem>
                                  );
                                })}
                              </SelectContent>
                            </Select>
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                    <FormField
                      control={form.control}
                      name="resources"
                      render={({ field }) => {
                        return (
                          <CustomTable
                            totalCount={resourceCount}
                            defaultFilterColumn="summary"
                            manualFiltering={false}
                            getRowId={(
                              originalRow: ResourceI,
                              index: number
                            ) => {
                              return originalRow.name;
                            }}
                            columns={resourceColumns}
                            synchroniseUrl={false}
                            data={resourceList}
                            initRowSelection={field.value}
                            initColumnVisibility={{
                              name: false,
                              methods: false,
                              description: false,
                            }}
                            onSelectionChange={(value: any) => {
                              console.log(value);
                              field.onChange(value);
                            }}
                          ></CustomTable>
                        );
                      }}
                    />
                  </div>
                  <Button disabled={loading} className="ml-auto" type="submit">
                    提交
                  </Button>
                </form>
              </Form>
            </div>
          </DialogContent>
        </Dialog>
      </div>
    </PageContainer>
  );
};

export default page;
